package drds.configuration.mvc.render;

import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

public class FileRender extends Render {

    static Logger logger = LoggerFactory.getLogger(FileRender.class);

    private File file;
    private String fileName;

    /**
     * 下载文件的时候要确保文件存在
     */
    public FileRender(File file, String fileName) {
        this.file = file;
        this.fileName = fileName;
    }

    @Override
    public void render() {
        // 下载文件的大小由应用程序控制
        if (file == null || !file.isFile() || file.length() > Long.MAX_VALUE) {
            return;
        }
        String[] dots = file.getName().split("\\.");
        if (dots.length < 1) {
            return;
        }

        HttpServletRequest request = getRequest();
        HttpServletResponse response = getResponse();
        response.reset();

        String agent = request.getHeader("USER-AGENT");
        String fileName = this.fileName;
        if (null != agent && (agent.contains("Trident") || agent.contains("Edge"))) {
            try {
                fileName = URLEncoder.encode(this.fileName, "UTF-8");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            try {
                fileName = MimeUtility.encodeText(this.fileName, "UTF8", "B");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setContentLength((int) file.length());
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setHeader("Connection", "close");


        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(file));
            outputStream = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = (inputStream.read(buffer))) != -1) {
                outputStream.write(buffer, 0, length);
            }
            outputStream.flush();
        } catch (Exception e) {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e1) {
                    logger.error(e1.getMessage());
                } finally {
                    // 调用垃圾收集器回收没有引用指向的流对象
                    outputStream = null;
                }
            }
            if (inputStream != null) {
                try {
                    // 调用垃圾收集器回收没有引用指向的流对象
                    inputStream.close();
                } catch (IOException e2) {
                    logger.error(e2.getMessage());
                } finally {
                    inputStream = null;
                }
            }
            try {// 调用垃圾收集器回收没有引用指向的流对象
                System.gc();
            } catch (Exception e2) {
            }
            throw new RenderException(e);
        } finally {

            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    logger.error(e.getMessage());
                } finally {
                    // 调用垃圾收集器回收没有引用指向的流对象
                    outputStream = null;
                }
            }
            if (inputStream != null) {
                try {
                    // 调用垃圾收集器回收没有引用指向的流对象
                    inputStream.close();
                } catch (IOException e) {
                    logger.error(e.getMessage());
                } finally {
                    inputStream = null;
                }
            }

        }
    }
}
